package com.ld.control.business.variable.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.control.business.process.model.ProcessNodeParamTmpModel;
import com.ld.control.business.process.model.ext.ProcessNodeExampleInfoExt;
import com.ld.control.business.process.service.ProcessNodeExampleService;
import com.ld.control.business.task.model.SubTaskExampleModel;
import com.ld.control.business.task.model.TaskExampleModel;
import com.ld.control.business.variable.mapper.VariableExampleMapper;
import com.ld.control.business.variable.mapper.VariableMapper;
import com.ld.control.business.variable.model.VariableExampleModel;
import com.ld.control.business.variable.model.VariableModel;
import com.ld.control.business.variable.service.VariableExampleService;
import com.ld.control.business.variable.service.VariableService;
import com.ld.control.business.variable.vo.req.VariableExampleReqVo;
import com.ld.control.business.variable.vo.resp.VariableExampleResp;
import com.ld.control.business.variable.vo.resp.VariableExampleValueResp;
import com.ld.control.exception.BusinessException;
import com.ld.control.sysenum.MethodParamTypeEnum;
import com.ld.control.sysenum.VariableValueTypeEnum;
import com.ld.control.utils.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import java.util.Date;
import java.util.List;

/**
 * <p>
 * 变量实例表 服务实现类
 * </p>
 *
 * @author wangfeng
 * @since 2024-04-23
 */
@Slf4j
@Service
public class VariableExampleServiceImpl extends ServiceImpl<VariableExampleMapper, VariableExampleModel> implements VariableExampleService {

    @Autowired
    private VariableExampleMapper variableExampleMapper;

    @Autowired
    private VariableService variableService;

    @Autowired
    private JWTUtils jwtUtils;

    @Autowired
    private ProcessNodeExampleService processNodeExampleService;

    @Override
    public VariableExampleResp getById(Long id) {
        VariableExampleResp variableExampleResp = new VariableExampleResp();
        VariableExampleModel variableExampleModel = variableExampleMapper.selectById(id);
        BeanUtils.copyProperties(variableExampleModel, variableExampleResp);
        return variableExampleResp;
    }

    @Override
    public IPage<VariableExampleResp> getPageList(String name, String taskExampleCode, Long subTaskExampleId, Long variableId, Integer current, Integer size) {
        IPage<VariableExampleResp> page = new Page<>(current, size);
        return variableExampleMapper.selectListByCondition(page, name,
                taskExampleCode, subTaskExampleId, variableId);
    }

    @Transactional
    @Override
    public void add(VariableExampleReqVo reqVo) {
        VariableExampleModel variableExampleModel = new VariableExampleModel();
        BeanUtils.copyProperties(reqVo, variableExampleModel);
        variableExampleModel.setArrayIndex(0);
        variableExampleModel.setCreateBy(jwtUtils.getCurrentUserAccountId());
        variableExampleModel.setCreateTime(new Date());
        variableExampleMapper.insert(variableExampleModel);
    }

    @Override
    public VariableExampleModel getSubTaskVariable(Long subTaskId, String variableName) {
        QueryWrapper<VariableExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(VariableExampleModel.SUB_TASK_EXAMPLE_ID, subTaskId);
        queryWrapper.eq(VariableExampleModel.NAME, variableName);
        return variableExampleMapper.selectOne(queryWrapper);
    }

    @Override
    public VariableExampleModel getTaskVariable(Long taskId, String variableName) {
        QueryWrapper<VariableExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(VariableExampleModel.TASK_EXAMPLE_ID, taskId);
        queryWrapper.eq(VariableExampleModel.NAME, variableName);
        return variableExampleMapper.selectOne(queryWrapper);
    }

    @Override
    public void setSubTaskVariable(Long subTaskId, String variableName, String variableValue) {

    }

    @Override
    public void setVariableValueById(Long id, String variableValue, boolean isCover) {
        VariableExampleModel variableExampleModel = variableExampleMapper.selectById(id);
        if (!isCover && variableExampleModel.getValueType().equals(MethodParamTypeEnum.ARRAY.getType())) {
            String value = variableExampleModel.getValue();
            List<String> valueArray = JSONObject.parseArray(value, String.class);
            valueArray.add(variableValue);
            variableValue = JSONArray.toJSONString(valueArray);
        }
        variableExampleModel.setValue(variableValue);
        variableExampleModel.setUpdateTime(new Date());
        variableExampleMapper.updateById(variableExampleModel);
    }

    @Override
    public String getArrayDataByPosition(Long id, Integer offset, Boolean moveFlag) {
        VariableExampleModel variableExampleModel = variableExampleMapper.selectById(id);
        Integer arrayIndex = variableExampleModel.getArrayIndex();
        String value = variableExampleModel.getValue();
        List<String> valueArray = JSONObject.parseArray(value, String.class);
        if (offset == 0) {
            return valueArray.get(arrayIndex);
        }
        if (offset > 0 && moveFlag) {
            arrayIndex = arrayIndex + offset;
            variableExampleModel.setArrayIndex(arrayIndex);
            variableExampleModel.setUpdateTime(new Date());
            variableExampleMapper.updateById(variableExampleModel);
            return valueArray.get(arrayIndex);
        }

        if (!moveFlag) {
            arrayIndex = offset - 1;
            return valueArray.get(arrayIndex);
        }

        return "";
    }

    @Override
    public VariableExampleModel initVariableExampleInfo(String variableName, Long processNodeExampleId) {
        log.info("initVariableExample variableName:{}", variableName);
        // 查询变量作用域
        VariableModel variableModel = variableService.getByName(variableName);
        ProcessNodeExampleInfoExt processNodeExampleModelExt = processNodeExampleService.getProcessNodeExampleModelExt(processNodeExampleId);
        TaskExampleModel taskExampleModel = processNodeExampleModelExt.getTaskExampleModel();
        SubTaskExampleModel subTaskExampleModel = processNodeExampleModelExt.getSubTaskExampleModel();

        if (variableModel.getScope() == 0) {
            VariableExampleModel variableExampleModel1 = getByName(processNodeExampleId, variableName);
            if (!ObjectUtils.isEmpty(variableExampleModel1)) {
                return variableExampleModel1;
            }
        }
        if (variableModel.getScope() == 1) {
            VariableExampleModel byTaskExampleId = getByTaskExampleId(taskExampleModel.getId(), variableName);
            if (!ObjectUtils.isEmpty(byTaskExampleId)) {
                return byTaskExampleId;
            }
        }

        if (variableModel.getScope() == 2) {
            VariableExampleModel byTaskExampleId = getBySubTaskExampleId(subTaskExampleModel.getId(), variableName);
            if (!ObjectUtils.isEmpty(byTaskExampleId)) {
                return byTaskExampleId;
            }
        }
        VariableExampleModel variableExampleModel = new VariableExampleModel();
        variableExampleModel.setVariableId(variableModel.getId());
        variableExampleModel.setName(variableModel.getName());
        variableExampleModel.setScope(variableModel.getScope());
        variableExampleModel.setValueType(variableModel.getValueType());
        if (!ObjectUtils.isEmpty(variableModel.getValue())) {
            variableExampleModel.setValue(variableModel.getValue());
            variableExampleModel.setDefaultValue(variableModel.getValue());
        } else {
            variableExampleModel.setValue(variableModel.getDefaultValue());
        }
        variableExampleModel.setArrayIndex(0);
        variableExampleModel.setTaskExampleId(taskExampleModel.getId());
        variableExampleModel.setTaskExampleCode(taskExampleModel.getCode());
        variableExampleModel.setTaskExampleName(taskExampleModel.getName());
        Integer scope = variableModel.getScope();
        if (scope == 2) {
            variableExampleModel.setSubTaskExampleId(subTaskExampleModel.getId());
            variableExampleModel.setSubTaskExampleName(subTaskExampleModel.getName());
        }
        variableExampleModel.setOffsetFlag(variableModel.getOffsetFlag());
        variableExampleModel.setCreateBy(jwtUtils.getCurrentUserAccountId());
        variableExampleModel.setCreateTime(new Date());
        variableExampleMapper.insert(variableExampleModel);
        return variableExampleModel;
    }

    @Override
    public VariableExampleModel getByName(Long processNodeExampleId, String variableName) {
        if (variableName.startsWith("@")) {
            // 去掉@前缀方便查询
            variableName = variableName.substring(1);
        }
        ProcessNodeExampleInfoExt processNodeExampleModelExt = processNodeExampleService.getProcessNodeExampleModelExt(processNodeExampleId);
        TaskExampleModel taskExampleModel = processNodeExampleModelExt.getTaskExampleModel();
        SubTaskExampleModel subTaskExampleModel = processNodeExampleModelExt.getSubTaskExampleModel();
        VariableModel variableModel = variableService.getByName(variableName);
        QueryWrapper<VariableExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(VariableExampleModel.NAME, variableName);
        if (variableModel.getScope() == 1) {
            queryWrapper.eq(VariableExampleModel.TASK_EXAMPLE_ID, taskExampleModel.getId());
        }
        if (variableModel.getScope() == 2) {
            queryWrapper.eq(VariableExampleModel.SUB_TASK_EXAMPLE_ID, subTaskExampleModel.getId());
        }
        return variableExampleMapper.selectOne(queryWrapper);
    }

    @Override
    public VariableExampleValueResp getByNameExt(Long processNodeExampleId, String variableName) {
        log.debug("getByNameV2 processNodeExampleId:{}, variableName:{}", processNodeExampleId, variableName);
        VariableExampleValueResp variableExampleValueResp = new VariableExampleValueResp();
        VariableExampleModel variableExampleModel = getByName(processNodeExampleId, variableName);
        variableExampleValueResp.setValueType(variableExampleModel.getValueType());
        variableExampleValueResp.setOffsetFlag(variableExampleModel.getOffsetFlag());
        if (variableExampleModel.getValueType().equals(MethodParamTypeEnum.ARRAY.getType()) && variableExampleModel.getOffsetFlag() == 1) {
            String value = variableExampleModel.getValue();
            Integer arrayIndex = variableExampleModel.getArrayIndex();
            List<String> valueList = JSONObject.parseArray(value, String.class);
            String realValue = valueList.get(arrayIndex);
            // 数组下标移动一位
            arrayIndex = arrayIndex + 1;
            variableExampleModel.setArrayIndex(arrayIndex);
            variableExampleModel.setUpdateTime(new Date());
            variableExampleMapper.updateById(variableExampleModel);
            variableExampleValueResp.setArrayIndex(arrayIndex);
            variableExampleValueResp.setOriginalValue(value);
            variableExampleValueResp.setCurrentValue(realValue);
            return variableExampleValueResp;
        }
        variableExampleValueResp.setOriginalValue(variableExampleModel.getValue());
        variableExampleValueResp.setCurrentValue(variableExampleModel.getValue());
        return variableExampleValueResp;
    }

    @Override
    public VariableExampleModel getByTaskExampleId(Long taskExampleId, String variableName) {
        if (variableName.startsWith("@")) {
            // 去掉@前缀方便查询
            variableName = variableName.substring(1);
        }
        QueryWrapper<VariableExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(VariableExampleModel.NAME, variableName);
        queryWrapper.eq(VariableExampleModel.TASK_EXAMPLE_ID, taskExampleId);
        return variableExampleMapper.selectOne(queryWrapper);
    }

    @Override
    public VariableExampleModel getBySubTaskExampleId(Long subTaskExampleId, String variableName) {
        if (variableName.startsWith("@")) {
            // 去掉@前缀方便查询
            variableName = variableName.substring(1);
        }
        QueryWrapper<VariableExampleModel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(VariableExampleModel.NAME, variableName);
        queryWrapper.eq(VariableExampleModel.SUB_TASK_EXAMPLE_ID, subTaskExampleId);
        return variableExampleMapper.selectOne(queryWrapper);
    }

    @Transactional
    @Override
    public void bindTaskVariable(TaskExampleModel taskExampleModel, String variableName, String variableValue) {
        log.info("bindTaskVariable:{}", variableValue);
        VariableModel variableModel = variableService.getByName(variableName);
        if (ObjectUtils.isEmpty(variableModel)) {
            throw new BusinessException(variableName + "-Variable name is empty");
        }
        VariableExampleModel variableExampleModel = new VariableExampleModel();
        variableExampleModel.setVariableId(variableModel.getId());
        variableExampleModel.setTaskExampleId(taskExampleModel.getId());
        variableExampleModel.setTaskExampleCode(taskExampleModel.getCode());
        variableExampleModel.setTaskExampleName(taskExampleModel.getName());
        variableExampleModel.setName(variableModel.getName());
        variableExampleModel.setScope(variableModel.getScope());
        variableExampleModel.setValueType(variableModel.getValueType());
        variableExampleModel.setValue(variableValue);
        variableExampleModel.setDefaultValue(variableValue);
        variableExampleModel.setArrayIndex(0);
        variableExampleModel.setCreateTime(new Date());
        variableExampleModel.setCreateBy(jwtUtils.getCurrentUserAccountId());
        variableExampleMapper.insert(variableExampleModel);
    }
}
